API Hooking Revealed

[역자주] 이 글은 CodeProject 사이트에 Ivo Ivanov가 "API hooking revealed"라는 제목으로 게재한 글입니다. Win32 시스템에서 API를 후킹하는 방법에 대한 전반적인 기법들을 다루고 있으며 자세한 설명이나 코드보다는 개념적인 내용들이 많아 Win32 SDK에 익숙치 않은 개발자들도 쉽게 접근할 수 있는 좋은 글인 것 같습니다. 원래 소스 파일이 함께 첨부되어 게재된 글인데 이 파일을 번역한 글과 함께 올리는 것은 혹시 저작권 문제가 될 수도 있다고 생각되어 따로 첨부하지 않았습니다. 소스 파일이 필요하신 분은 원문인 "API hooking revealed"에서 다운받아 사용하시기 바랍니다.
이 글을 읽고 제대로 이해하려면 최소한 윈도우즈 메시지 후킹과 DLL의 기본 구조에 대해서는 알아야 합니다. 이런 내용들은 MSDN에 잘 설명되어 있고 codeproject, codeguru, devpia 등의 사이트에도 좋은 글들이 많이 게재되어 있으니 참고하시기 바랍니다.

어떤 윈도우즈 어플리케이션을 개발하기 위해서 우리들은 여러 종류의 언어나 도구들을 사용할 수 있습니다. Visual Basic, Visual C++, Delphi, C++ Builder, PowerBuilder 등 수많은 언어와 도구들이 있습니다.
이런 프로그램들에서 어떤 작업을 수행하기 위해서 사용하는 방법은 서로 다를지라도 그 내부로 들어가 보면 결국에는 윈도우즈 운영체제에서 제공하는 API를 호출하게 됩니다. 예를 들어 화면에 문자열을 출력하려고 한다면 MFC에서는 CDC::DrawText를 사용하고 Dephi에서는 TCanvas::TextOut을 사용합니다. 도구마다 사용하는 형태는 이렇게 다르지만 결국에는 TextOutA/W API를 호출합니다.
TextOutA/W API는 gdi32.dll에 구현되어 있는 함수이고 운영체제가 제공하는 API입니다. 윈도우즈는 기본적으로 3개의 DLL-kernel32.dll, user32.dll, gdi32.dll-에 대부분의 API를 구현하여 제공하고 어플리케이션은 실행시 자신의 프로세스 주소 공간으로 이들 DLL을 매핑한 후 사용합니다.
API 후킹은 어떤 프로그램에서 API 호출을 하는 것을 가로채서 개발자가 만든 프로그램의 함수가 처리할 수 있도록 하는 메카니즘을 말합니다. 반드시 윈도우즈의 API일 필요는 없고 단지 DLL에서 구현하여 제공하는 함수이면 됩니다.
API 후킹은 어떤 언어로 개발된 프로그램에도 적용될 수 있으며 디버깅이나 트레이싱 작업, 모니터링 작업 등에 사용할 수 있으며 소스 코드가 없는 프로그램에 기능을 추가하기 위한 용도로도 사용할 수 있습니다. 그외에도 여러가지 용도로 사용할 수 있지만 굳이 이런 프로그램을 개발할 계획이 아니더라도 윈도우즈 프로그램의 기본적인 원리를 이해하는데 많은 도움이 됩니다.
API 후킹을 적용하여 만든 프로그램 중에 주위에서 일반적으로 볼 수 있는 것으로는 myQuickFind, 아래한글사전과 같은 전자 사전 프로그램이 있습니다. 이런 프로그램들은 모두 다른 윈도우의 마우스 커서 밑에 있는 단어를 인식할 수 있는 기능을 가지고 있는데 이것은 윈도우즈 메시지 후킹과 API 후킹(TextOutA/W)을 이용한 것입니다.
또한 크래킹이나 스파이웨어를 개발하는데 악용될 수도 있고 반대로 방지하는 용도로도 사용될 수 있습니다. 어찌되었든 간에 이 글이 윈도우즈 환경에서 개발을 하시는 많은 분들에게 도움이 되기를 바랍니다.

번역해서 글을 올리는 것이 처음이어서 어색한 부분들이 많습니다. 게다가 저자가 쉼표를 생략하는 동격 명사 구문이나 분사 구문을 많이 사용하였고 번역이 표준화되지 않은 개발 관련 용어들도 많아 더욱 그렇습니다. 그래서 원문과 번역문을 함께 올렸고 번역이 미비하거나 어색한 부분에는 [역자주]를 달아 놓았습니다. 그래도 이상한 부분들은 코멘트를 달아 주시면 가능하면 수정해서 다시 올리도록 하겠습니다.

Introduction(소개)

Intercepting Win32 API calls has always been a challenging subject among most of the Windows developers and I have to admit, it's been one of my favorite topics. The term Hooking represents a fundamental technique of getting control over a particular piece of code execution. It provides an straightforward mechanism that can easily alter the operating system's behavior as well as 3rd party products, without having their source code available.

Win32 API 호출을 가로채는 것은 대다수의 윈도우즈 개발자들 사이에서 항상 도전하는 과제이었으며 내가 가장 좋아하는 주제 중의 하나가 되었다. 후킹이라는 단어는 코드 실행의 특정 부분을 제어할 수 있는 기반 기술을 의미한다. 후킹은 써드 파티 제품뿐 아니라 운영체제의 동작까지도 소스 코드 없이 쉽게 바꿀 수 있는 간편한 메카니즘을 제공한다.

Many modern systems draw the attention to their ability to utilize existing Windows applications by employing spying techniques. A key motivation for hooking, is not only to contribute to advanced functionalities, but also to inject user-supplied code for debugging purposes.

많은 현대적인 시스템들이 스파이 기술을 사용하여 기존의 윈도우즈 어플리케이션을 활용하는 것에 관심을 기울이고 있다. 후킹을 연구하는 주요 동기는 향상된 기능을 제공하는 것 뿐 아니라 디버깅을 목적으로 사용자 정의 코드를 침투시키는 것에 있다.

Unlike some relatively "old" operating systems like DOS and Windows 3.xx, the present Windows OS as NT/2K and 9x provide sophisticated mechanisms to separate address spaces of each process. This architecture offers a real memory protection, thus no application is able to corrupt the address space of another process or in the worse case even to crash the operating system itself. This fact makes a lot harder the development of system-aware hooks.

DOS, 윈도우즈3.XX와 같이 상대적으로 오래된 운영체제와 달리, NT/2K,9x와 같은 현재의 윈도우즈 OS는 각각의 프로세스의 주소 공간을 분리하는 정교한 메카니즘을 제공한다. 이러한 구조는 실제 메모리 보호를 제공하여 어떠한 어플리케이션도 다른 프로세스의 주소 공간을 변형시키거나 더 나아가 운영 체제 자체를 망가뜨리지 못하도록 한다. 이러한 이유로 시스템 후킹의 개발은 더욱 어려워졌다.

My motivation for writing this article was the need for a really simple hooking framework, that will offer an easy to use interface and ability to capture different APIs. It intends to reveal some of the tricks that can help you to write your own spying system. It suggests a single solution how to build a set for hooking Win32 API functions on NT/2K as well as 98/Me (shortly named in the article 9x) family Windows. For the sake of simplicity I decided not to add a support do UNICODE. However, with some minor modifications of the code you could easily accomplish this task.

이 글을 쓰게 된 동기는 사용하기 쉽고 다른 API들을 가로챌 수 있는 매우 간단한 후킹 프레임웍에 대한 필요성 때문이다. 이 글에서 스파이 시스템을 구축하기 위해 필요한 몇가지 트릭들을 밝힐 계획이다. 이 글은 98/Me와 NT/2K 에서 모두 사용할 수 있는 Win32 API 함수 후킹에 대한 하나의 솔루션을 제안한다. 단순하게 하기 위하여 UNICODE에 대한 지원은 추가하지 않기로 하였다. 하지만 코드를 약간 수정하면 UNICODE에 대한 지원을 쉽게 달성할 수 있을 것이다.

Spying of applications provides many advantages:

어플리케이션을 스파이하는 것은 다음과 같은 많은 이점을 제공한다: